package com.sjf.day02.Queue;

/**
 * 环形队列
 *
 * @author <huangtang>
 * @since 2021/12/16 10:36
 **/
public class CircleQueue {
    private int maxSize;//数组最大容量
    private int front;//指向队列的第一个元素
    private int rear;//指向队列的最后一个元素的后一个位置
    private int[] arr;

    public CircleQueue(int maxSize) {
        this.maxSize = maxSize;
        this.front = 0;
        this.rear = 0;
        this.arr = new int[this.maxSize];
    }

    /**
     * 判断队列是否已满
     * @return
     */
    public boolean isFull(){
        return (rear+1)%maxSize==front ; // rear+1 是因为尾巴留了一个位置
    }

    /**
     * 判断队列是否为空
     * @return
     */
    public boolean isEmpty(){
        return front==rear;
    }

    /**
     * 添加一个数到队列中
     * @param n
     */
    public void addQueue(int n){
        if(isFull()){
            System.out.println("队列满,不能加入数据");
            return;
        }
        arr[rear]=n;
        //添加数据后rear向后移一位，如果在最后一位，考虑对maxSize取模，防止溢出
        rear = (rear+1)%maxSize;
    }

    /**
     * 从队列中取出一个数
     * @return
     * @throws Exception
     */
    public int getQueue() throws Exception {
        if(isEmpty()){
           throw new Exception("队列空，不能取出数据");
        }
        int value = arr[front];
        // 取出数据front向后移一位，如果在最后一位，考虑对maxSize取模，防止溢出
        front = (front+1)%maxSize;
        return value;
    }

    /**
     * 显示队列中的所有数
     */
    public void showQueue(){
        if(isEmpty()){
            System.out.println("队列为空，没有数据");
            return;
        }
        for (int i = front; i < front+size(); i++) {
            System.out.printf("arr[%d]=%d\n",i%maxSize,arr[i%maxSize]);
        }
    }

    /**
     * 求出当前队列有效数据个数
     * @return
     */
    public int size(){
        return (rear+maxSize-front)%maxSize;
    }

    /**
     * 取出队列头数据
     * @return
     * @throws Exception
     */
    public int headQueue() throws Exception {
        if(isEmpty()){
            throw new Exception("队列为空，不能取出数据");
        }
        return arr[front];
    }

}
